package com.wf.day_0618.test1;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author mpk
 * @since 2024/6/18 19:20:49
 */
public class TestD {
/*    已知一个类，定义如下package com.igeek;
    public class DemoClass {
        public void run() {
            System.out.println("welcome to igeek!");
        }
    }
(1)写一个Properties格式的配置文件，配置类的完整名称。
            (2)写一个程序，读取这个Properties配置文件，获得类的完整名称并加载这个类。
            (3)用反射的方式运行run方法。*/

    public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {


        /*
         * 加载配置文件DemoClass.properties，该文件应位于与TestD类相同的资源目录下。
         * 这里使用getResourceAsStream方法来获取文件的输入流，以便后续加载属性文件。
         */
        InputStream stream = TestD.class.getResourceAsStream("DemoClass.properties");

        /*
         * 创建一个Properties对象，用于加载和存储属性文件中的键值对。
         */
        Properties properties = new Properties();

        /*
         * 从输入流中加载属性文件内容到Properties对象中。
         */
        properties.load(stream);

        /*
         * 从属性文件中获取className属性的值，该值表示需要实例化的类的名称。
         */
        String className = properties.getProperty("className");

        /*
         * 使用获取到的类名，通过Class.forName方法动态加载类，并返回Class对象。
         */
        Class<?> aClass = Class.forName(className);

        /*
         * 使用反射机制，创建上一步加载的类的实例。
         * 这里使用newInstance方法，该方法已过时，但为了兼容性使用。
         */
        Object o = aClass.newInstance();

        /*
         * 获取实例对象上的名为run的方法，该方法没有参数。
         * 使用getMethod方法获取公共方法，需要指定方法名和参数类型。
         */
        Method run = aClass.getMethod("run");

        /*
         * 调用获取到的run方法，传入实例对象作为目标对象进行方法调用。
         * 使用invoke方法可以动态调用对象的方法。
         */
        run.invoke(o);

        /*
         * 如果输入流不为空，则关闭输入流。
         * 关闭资源是良好的编程习惯，可以释放系统资源。
         */
        if (stream != null) {
            stream.close();
        }



    }

}
